package cn.com.cifi.mars.web.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONObject;

import cn.com.cifi.mars.common.bean.R;
import cn.com.cifi.mars.common.redis.RedisTemplateUtil;
import cn.com.cifi.mars.constant.CodeEnum;
import cn.com.cifi.mars.entity.common.IdmUser;
import cn.com.cifi.mars.util.WebUtils;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class SessionFilter implements Filter {

	private RedisTemplateUtil redisTemplateUtil;

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest req = (HttpServletRequest) request;

		String contextPath = ((HttpServletRequest) request).getContextPath();

		if (req.getRequestURI().startsWith(contextPath + "/healthCheck")
				|| req.getRequestURI().startsWith(contextPath + "/login")
				|| (req.getRequestURI().indexOf("download") > 0) || (req.getRequestURI().indexOf("export") > 0)
				|| (req.getRequestURI().indexOf("/valueApprovel/app/") > 0)
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/masterToMars")
				|| req.getRequestURI().startsWith(contextPath + "/api/sso")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/esbSync")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/idmSync")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/idm/sync")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/demo/loginTmp")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/signPlan/signPlanVersion/approvalPreviewApp")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/returnPlan/approvalPreviewApp")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/returnCoefficient/approvalPreviewApp")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/sys/org")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/monitoringConsole/updateAppEliminateToDo")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/monitoringConsole/getAppToDo")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/common/getAppToDo")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/common/cleanAppToDo")
				|| req.getRequestURI().startsWith(contextPath + "/api/v1/common/handleData")
				|| (isPC(req) && (req.getRequestURI().startsWith(contextPath + "/api/v1/common/getWarnPcToDo")))
				|| (isPC(req) && (req.getRequestURI().startsWith(contextPath + "/api/v1/common/cleanPcToDo")))) {
			chain.doFilter(request, response);
			return;
		}

		String sessionToken = req.getHeader("sessionToken");
		if (sessionToken == null) {
			sessionToken = req.getParameter("sessionToken");
		}

		IdmUser sessionUser = null;

		try {

			sessionUser = (IdmUser) redisTemplateUtil.get("mars_user_" + sessionToken);
			if (sessionUser == null) {
				R r = new R();
				r.setCode(CodeEnum.NONE_PERMISSION_ERROR.getCode());
				r.setMessage(CodeEnum.NONE_PERMISSION_ERROR.getMessage());
				response.getWriter().println(JSONObject.toJSONString(r));
				return;
			}

			log.info("{} -> {}", sessionUser.getUsername(), req.getRequestURI());

		} catch (Exception e) {
			if (sessionUser != null) {
				log.info("{} login error, {}", sessionUser.getUsername(), e.getMessage());
			} else {
				log.info("login error, {}", e.getMessage());
			}

			R r = new R();
			r.setCode(CodeEnum.NONE_PERMISSION_ERROR.getCode());
			r.setMessage(CodeEnum.NONE_PERMISSION_ERROR.getMessage());
			response.getWriter().println(JSONObject.toJSONString(r));

			return;

		}

		chain.doFilter(request, response);

	}

	private boolean isPC(HttpServletRequest req) {
		String sourceString = WebUtils.getSource(req);
		if (sourceString.indexOf("PC") > 0) {
			return false;
		}
		return true;
	}

	public void destroy() {
		redisTemplateUtil = null;
	}

	public void init(FilterConfig filterConfig) {
	}

	public void setTemplate(RedisTemplateUtil redisTemplateUtil) {
		this.redisTemplateUtil = redisTemplateUtil;
	}
}